// Created: Dec 14, 2014
//
// Author: wjinwen.1988@gmail.com

#ifndef CHI_NET_SOCKET_H
#define CHI_NET_SOCKET_H

#include <netinet/in.h>

#include <string>

namespace chi {
namespace net {

class InetAddress;

class Socket {
 public:
  Socket(const int fd);
  ~Socket();

  int fd() const { return fd_; }

  bool BindAddress(const InetAddress& addr);
  bool Listen();

  // On success, return a non-negative interger that is
  // a descriptor for the accepted socket.
  int Accept(InetAddress* peeraddr);

  void ShutdownWrite();

  // Enable/disable SO_KEEPALIVE
  void SetKeepAlive(bool on);
  // Enable/disable SO_REUSEADDR
  void SetReuseAddress(bool on);
  // Enable/disable TCP_NODELAY
  void SetTcpNoDelay(bool nodelay);
  // Set bloking or non-blocking
  void SetSoBlocking(bool on);

  // 创建一个socket，并设置FD_CLOEXEC属性。
  // 在程序退出后，socket可以自动关闭。
  static int CreateSocketCloseOnExec();
  // 创建一个非阻塞的socket，并设置FD_CLOEXEC属性。
  static int CreateSocketNonblockingOrDie();
  
  // 根据指定的socket获取本地地址
  static struct sockaddr_in GetLocalAddr(int sockfd);
  // 根据指定的socket获取对端的地址
  static struct sockaddr_in GetPeerAddr(int socfd);
 private:
  const int fd_;
};

} 
}

#endif

